package com.kzj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.kzj.common.FailMsgConstant;
import com.kzj.common.GlobalConstant;
import com.kzj.common.utils.VerifyUtil;
import com.kzj.domain.User;
import com.kzj.dao.UserDao;
import com.kzj.domain.dto.LoginDto;
import com.kzj.myJar.common.constant.ExceptionConstant;
import com.kzj.myJar.common.exception.BaseException;
import com.kzj.myJar.common.exception.ParamException;
import com.kzj.myJar.common.result.Result;
import com.kzj.myJar.common.utils.StringUtil;
import com.kzj.myJar.springboot.common.util.JwtUtil;
import com.kzj.myJar.springboot.redis.RedisJsonUtil;
import com.kzj.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.DigestUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author kzj
 * @since 2024-11-27
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {
    @Value("${app.jwt.secret}")
    public String jwtSecret;
    @Override
    public String login(LoginDto loginDto, String cookie) {
        Assert.isTrue(StringUtil.isNotBlank(cookie),FailMsgConstant.ILLEGAL_REQUEST);
        String key= GlobalConstant.COOKIES_KEY_PREFIX+cookie;
        String code = RedisJsonUtil.get(key);
        Assert.isTrue(StringUtil.isNotBlank(code),FailMsgConstant.VERIFY_CODE_NOT_FOUND);
        Assert.isTrue(code.equals(loginDto.getVerifyCode()),FailMsgConstant.VERIFY_CODE_ERROR);
        Assert.isTrue(StringUtil.isNotBlank(loginDto.getEmail())||StringUtil.isNotBlank(loginDto.getEmail()),FailMsgConstant.ACCOUNT_NUMBER_NULL);
        User user=null;
        if(StringUtil.isNotBlank(loginDto.getPassword())){
            if(StringUtil.isNotBlank(loginDto.getEmail())){
                Assert.isTrue(VerifyUtil.verifyEmail(loginDto.getEmail()), FailMsgConstant.EMAIL_FORMAT_ERROR);
                user=getOne(new LambdaQueryWrapper<User>().eq(User::getEmail,loginDto.getEmail()));
            }else{
                Assert.isTrue(VerifyUtil.verifyPhone(loginDto.getPhone()), FailMsgConstant.PHONE_FORMAT_ERROR);
                user=getOne(new LambdaQueryWrapper<User>().eq(User::getPhone,loginDto.getPhone()));
            }
            if(user==null){
                user=new User();
                user.setEmail(loginDto.getEmail());
                user.setPhone(loginDto.getPhone());
                user.setSalt(UUID.randomUUID().toString().replace("-",""));
                user.setPassword(DigestUtils.md5DigestAsHex((loginDto.getPassword()+user.getSalt()).getBytes()));
                save(user);
            }else{
                Assert.isTrue(DigestUtils.md5DigestAsHex((loginDto.getPassword()+user.getSalt()).getBytes()).equals(user.getPassword()),FailMsgConstant.PASSWORD_ERROR);
            }
        }else if(StringUtil.isNotBlank(loginDto.getAuthCode())){
            String authCodeKey=null;
            if(StringUtil.isNotBlank(loginDto.getEmail())){
                Assert.isTrue(VerifyUtil.verifyEmail(loginDto.getEmail()), FailMsgConstant.EMAIL_FORMAT_ERROR);
                authCodeKey=GlobalConstant.EMAIL_KEY_PREFIX+loginDto.getEmail();
                user=getOne(new LambdaQueryWrapper<User>().eq(User::getEmail,loginDto.getEmail()));
            }else{
                Assert.isTrue(VerifyUtil.verifyPhone(loginDto.getPhone()), FailMsgConstant.PHONE_FORMAT_ERROR);
                authCodeKey=GlobalConstant.PHONE_KEY_PREFIX+loginDto.getPhone();
                user=getOne(new LambdaQueryWrapper<User>().eq(User::getPhone,loginDto.getPhone()));
            }
            String authCode = RedisJsonUtil.get(authCodeKey);
            Assert.isTrue(StringUtil.isNotBlank(authCode),FailMsgConstant.AUTH_CODE_NOT_FOUND);
            Assert.isTrue(authCode.equals(loginDto.getAuthCode()),FailMsgConstant.AUTH_CODE_ERROR);
            if(user==null){
                user=new User();
                user.setEmail(loginDto.getEmail());
                user.setPhone(loginDto.getPhone());
                user.setSalt(UUID.randomUUID().toString().replace("-",""));
                save(user);
            }
        }else{
            throw new ParamException(ExceptionConstant.PARAM_NO_NULL);
        }
        Map<String,Object> map=new HashMap<>();
        map.put(GlobalConstant.USER_ID, user.getId());
        String jwt = JwtUtil.createJwt(map, jwtSecret, GlobalConstant.JWT_VALID_TTL, TimeUnit.MINUTES);
        RedisJsonUtil.set(GlobalConstant.TOKEN_KEY_PREFIX+jwt,"",GlobalConstant.JWT_VALID_TTL,TimeUnit.MINUTES);
        return jwt;
    }
}
